{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "02_NumPy",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "metadata": {
        "id": "bOChJSNXtC9g",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# NumPy"
      ]
    },
    {
      "metadata": {
        "id": "OLIxEDq6VhvZ",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "<img src=\"https://raw.githubusercontent.com/GokuMohandas/practicalAI/master/images/logo.png\" width=150>\n",
        "\n",
        "In this lesson we will learn the basics of numerical analysis using the NumPy package.\n",
        "\n",
        "<img src=\"https://raw.githubusercontent.com/GokuMohandas/practicalAI/master/images/numpy.png\" width=300>\n",
        "\n",
        "\n"
      ]
    },
    {
      "metadata": {
        "id": "VoMq0eFRvugb",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# NumPy basics"
      ]
    },
    {
      "metadata": {
        "id": "0-dXQiLlTIgz",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "import numpy as np"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "bhaOPJV7WA0m",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# Set seed for reproducibility\n",
        "np.random.seed(seed=1234)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "23tSlin9aWZ8",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 102
        },
        "outputId": "4df1dbc0-77a1-4776-87d2-326b0bb0f79c"
      },
      "cell_type": "code",
      "source": [
        "# Scalars\n",
        "x = np.array(6) # scalar\n",
        "print (\"x: \", x)\n",
        "# Number of dimensions\n",
        "print(\"x ndim: \", x.ndim)\n",
        "# Dimensions\n",
        "print(\"x shape:\", x.shape)\n",
        "# Size of elements\n",
        "print(\"x size: \", x.size)\n",
        "# Data type\n",
        "print (\"x dtype: \", x.dtype)"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x:  6\n",
            "x ndim:  0\n",
            "x shape: ()\n",
            "x size:  1\n",
            "x dtype:  int64\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "ugIZprdIabFF",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 102
        },
        "outputId": "485b9e5e-176a-4ac3-b5ac-71a951470bf1"
      },
      "cell_type": "code",
      "source": [
        "# 1-D Array\n",
        "x = np.array([1.3 , 2.2 , 1.7])\n",
        "print (\"x: \", x)\n",
        "print(\"x ndim: \", x.ndim)\n",
        "print(\"x shape:\", x.shape)\n",
        "print(\"x size: \", x.size)\n",
        "print (\"x dtype: \", x.dtype) # notice the float datatype"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x:  [1.3 2.2 1.7]\n",
            "x ndim:  1\n",
            "x shape: (3,)\n",
            "x size:  3\n",
            "x dtype:  float64\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "SQI-T_4MbE9J",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 153
        },
        "outputId": "4eede496-01c0-4f83-d0d9-ffe073de8f9f"
      },
      "cell_type": "code",
      "source": [
        "# 3-D array (matrix)\n",
        "x = np.array([[[1,2,3], [4,5,6], [7,8,9]]])\n",
        "print (\"x:\\n\", x)\n",
        "print(\"x ndim: \", x.ndim)\n",
        "print(\"x shape:\", x.shape)\n",
        "print(\"x size: \", x.size)\n",
        "print (\"x dtype: \", x.dtype)"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x:\n",
            " [[[1 2 3]\n",
            "  [4 5 6]\n",
            "  [7 8 9]]]\n",
            "x ndim:  3\n",
            "x shape: (1, 3, 3)\n",
            "x size:  9\n",
            "x dtype:  int64\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "z2Qf8EKZln9j",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 221
        },
        "outputId": "45b92bcd-42a4-457b-ae34-494a1f214ffe"
      },
      "cell_type": "code",
      "source": [
        "# Functions\n",
        "print (\"np.zeros((2,2)):\\n\", np.zeros((2,2)))\n",
        "print (\"np.ones((2,2)):\\n\", np.ones((2,2)))\n",
        "print (\"np.eye((2)):\\n\", np.eye((2)))\n",
        "print (\"np.random.random((2,2)):\\n\", np.random.random((2,2)))"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "np.zeros((2,2)):\n",
            " [[0. 0.]\n",
            " [0. 0.]]\n",
            "np.ones((2,2)):\n",
            " [[1. 1.]\n",
            " [1. 1.]]\n",
            "np.eye((2)):\n",
            " [[1. 0.]\n",
            " [0. 1.]]\n",
            "np.random.random((2,2)):\n",
            " [[0.19151945 0.62210877]\n",
            " [0.43772774 0.78535858]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "qVD-MCiCdcV9",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# Indexing"
      ]
    },
    {
      "metadata": {
        "id": "vyt36kFOcVDX",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        },
        "outputId": "d65f99dd-97ba-4df5-afa1-fc4305c0dc69"
      },
      "cell_type": "code",
      "source": [
        "# Indexing\n",
        "x = np.array([1, 2, 3])\n",
        "print (\"x[0]: \", x[0])\n",
        "x[0] = 0\n",
        "print (\"x: \", x)"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x[0]:  1\n",
            "x:  [0 2 3]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "qxHww0didni6",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 170
        },
        "outputId": "0cccf1f5-3372-4f75-baf9-095b546e9ced"
      },
      "cell_type": "code",
      "source": [
        "# Slicing\n",
        "x = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n",
        "print (x)\n",
        "print (\"x column 1: \", x[:, 1]) \n",
        "print (\"x row 0: \", x[0, :]) \n",
        "print (\"x rows 0,1,2 & cols 1,2: \\n\", x[:3, 1:3]) "
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[ 1  2  3  4]\n",
            " [ 5  6  7  8]\n",
            " [ 9 10 11 12]]\n",
            "x column 1:  [ 2  6 10]\n",
            "x row 0:  [1 2 3 4]\n",
            "x rows 0,1,2 & cols 1,2: \n",
            " [[ 2  3]\n",
            " [ 6  7]\n",
            " [10 11]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "A52pzB9idyDE",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 119
        },
        "outputId": "c9cd9a42-8cbb-4459-b878-8969aaec1e95"
      },
      "cell_type": "code",
      "source": [
        "# Integer array indexing\n",
        "print (x)\n",
        "rows_to_get = np.arange(len(x))\n",
        "print (\"rows_to_get: \", rows_to_get)\n",
        "cols_to_get = np.array([0, 2, 1])\n",
        "print (\"cols_to_get: \", cols_to_get)\n",
        "print (\"indexed values: \", x[rows_to_get, cols_to_get])"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[ 1  2  3  4]\n",
            " [ 5  6  7  8]\n",
            " [ 9 10 11 12]]\n",
            "rows_to_get:  [0 1 2]\n",
            "cols_to_get:  [0 2 1]\n",
            "indexed values:  [ 1  7 10]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "_R7O5WsVfDij",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 187
        },
        "outputId": "ab346ca7-5959-4bd2-cf02-9d2f9b253e72"
      },
      "cell_type": "code",
      "source": [
        "# Boolean array indexing\n",
        "x = np.array([[1,2], [3, 4], [5, 6]])\n",
        "print (\"x:\\n\", x)\n",
        "print (\"x > 2:\\n\", x > 2)\n",
        "print (\"x[x > 2]:\\n\", x[x > 2])"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x:\n",
            " [[1 2]\n",
            " [3 4]\n",
            " [5 6]]\n",
            "x > 2:\n",
            " [[False False]\n",
            " [ True  True]\n",
            " [ True  True]]\n",
            "x[x > 2]:\n",
            " [3 4 5 6]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "77RCjrQ8gvYW",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# Array math"
      ]
    },
    {
      "metadata": {
        "id": "1UJVcNCLfFrV",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 170
        },
        "outputId": "4284fa79-10e7-428a-f30e-7a59a16cf510"
      },
      "cell_type": "code",
      "source": [
        "# Basic math\n",
        "x = np.array([[1,2], [3,4]], dtype=np.float64)\n",
        "y = np.array([[1,2], [3,4]], dtype=np.float64)\n",
        "print (\"x + y:\\n\", np.add(x, y)) # or x + y\n",
        "print (\"x - y:\\n\", np.subtract(x, y)) # or x - y\n",
        "print (\"x * y:\\n\", np.multiply(x, y)) # or x * y"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x + y:\n",
            " [[2. 4.]\n",
            " [6. 8.]]\n",
            "x - y:\n",
            " [[0. 0.]\n",
            " [0. 0.]]\n",
            "x * y:\n",
            " [[ 1.  4.]\n",
            " [ 9. 16.]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "1BV0nSIliMC6",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "<img src=\"https://raw.githubusercontent.com/GokuMohandas/practicalAI/master/images/matrix.png\" width=400>\n"
      ]
    },
    {
      "metadata": {
        "id": "XyZVF6gXhTWd",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        },
        "outputId": "8cbc328a-b5f3-416e-cf6f-a140aa208398"
      },
      "cell_type": "code",
      "source": [
        "# Dot product\n",
        "a = np.array([[1,2,3], [4,5,6]], dtype=np.float64) # we can specify dtype\n",
        "b = np.array([[7,8], [9,10], [11, 12]], dtype=np.float64)\n",
        "print (a.dot(b))"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[ 58.  64.]\n",
            " [139. 154.]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "7pB-H-7phsku",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 102
        },
        "outputId": "96a21872-164a-4b47-cd35-bf031a7421d3"
      },
      "cell_type": "code",
      "source": [
        "# Sum across a dimension\n",
        "x = np.array([[1,2],[3,4]])\n",
        "print (x)\n",
        "print (\"sum all: \", np.sum(x)) # adds all elements\n",
        "print (\"sum by col: \", np.sum(x, axis=0)) # add numbers in each column\n",
        "print (\"sum by row: \", np.sum(x, axis=1)) # add numbers in each row"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[1 2]\n",
            " [3 4]]\n",
            "sum all:  10\n",
            "sum by col:  [4 6]\n",
            "sum by row:  [3 7]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "pLDG49LrijgA",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 119
        },
        "outputId": "9fa3a3e1-6a33-4052-baea-3dd91649f193"
      },
      "cell_type": "code",
      "source": [
        "# Transposing\n",
        "print (\"x:\\n\", x)\n",
        "print (\"x.T:\\n\", x.T)"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x:\n",
            " [[1 2]\n",
            " [3 4]]\n",
            "x.T:\n",
            " [[1 3]\n",
            " [2 4]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "KdPKVKtwkWnw",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# Advanced"
      ]
    },
    {
      "metadata": {
        "id": "U_j2fCcjkEyo",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 119
        },
        "outputId": "7df2d80f-7e31-4c01-e8e7-81c6986f6bd7"
      },
      "cell_type": "code",
      "source": [
        "# Tile\n",
        "x = np.array([[1,2], [3,4]])\n",
        "y = np.array([5, 6])\n",
        "addent = np.tile(y, (len(x), 1))\n",
        "print (\"addent: \\n\", addent)\n",
        "z = x + addent\n",
        "print (\"z:\\n\", z)"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "addent: \n",
            " [[5 6]\n",
            " [5 6]]\n",
            "z:\n",
            " [[ 6  8]\n",
            " [ 8 10]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "1NsoFVo0mfQ4",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 68
        },
        "outputId": "3b2a830e-abcf-4e5d-e824-2b9ce142f166"
      },
      "cell_type": "code",
      "source": [
        "# Broadcasting\n",
        "x = np.array([[1,2], [3,4]])\n",
        "y = np.array([5, 6])\n",
        "z = x + y\n",
        "print (\"z:\\n\", z)"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "z:\n",
            " [[ 6  8]\n",
            " [ 8 10]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "RdEHrnMTnO6k",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 153
        },
        "outputId": "881c6cf7-bfc7-4c41-ad70-68cd01b20656"
      },
      "cell_type": "code",
      "source": [
        "# Reshaping\n",
        "x = np.array([[1,2], [3,4], [5,6]])\n",
        "print (x)\n",
        "print (\"x.shape: \", x.shape)\n",
        "y = np.reshape(x, (2, 3))\n",
        "print (\"y.shape: \", y.shape)\n",
        "print (\"y: \\n\", y)"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[1 2]\n",
            " [3 4]\n",
            " [5 6]]\n",
            "x.shape:  (3, 2)\n",
            "y.shape:  (2, 3)\n",
            "y: \n",
            " [[1 2 3]\n",
            " [4 5 6]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "tE1BmoJuns70",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 102
        },
        "outputId": "719b9e01-4428-4013-b413-d755d46a2e58"
      },
      "cell_type": "code",
      "source": [
        "# Removing dimensions\n",
        "x = np.array([[[1,2,1]],[[2,2,3]]])\n",
        "print (\"x.shape: \", x.shape)\n",
        "y = np.squeeze(x, 1) # squeeze dim 1\n",
        "print (\"y.shape: \", y.shape) \n",
        "print (\"y: \\n\", y)"
      ],
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x.shape:  (2, 1, 3)\n",
            "y.shape:  (2, 3)\n",
            "y: \n",
            " [[1 2 1]\n",
            " [2 2 3]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "LNYJRMF4qvXN",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 119
        },
        "outputId": "be32eb32-2222-4178-fb52-4fc86d5f8df1"
      },
      "cell_type": "code",
      "source": [
        "# Adding dimensions\n",
        "x = np.array([[1,2,1],[2,2,3]])\n",
        "print (\"x.shape: \", x.shape)\n",
        "y = np.expand_dims(x, 1) # expand dim 1\n",
        "print (\"y.shape: \", y.shape) \n",
        "print (\"y: \\n\", y)"
      ],
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "x.shape:  (2, 3)\n",
            "y.shape:  (2, 1, 3)\n",
            "y: \n",
            " [[[1 2 1]]\n",
            "\n",
            " [[2 2 3]]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "XthM4y7SotAH",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# Additional resources"
      ]
    },
    {
      "metadata": {
        "id": "3KmESFstrbFS",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "You don't have to memorize anything here and we will be taking a closer look at NumPy in the later lessons. If you are curious about more checkout the [NumPy reference manual](https://docs.scipy.org/doc/numpy-1.15.1/reference/)."
      ]
    }
  ]
}
